package com.bolt.report.engine.export.html;

import com.bolt.common.collection.MapUtil;
import com.bolt.common.utils.StrUtil;
import com.bolt.common.web.RequestUtil;
import com.bolt.report.definition.HyperlinkDefinition;
import com.bolt.report.engine.BindData;
import com.bolt.report.engine.ReportConstants;
import com.bolt.report.engine.fill.BaseFillElement;
import com.bolt.report.engine.fill.FillContext;
import com.bolt.report.engine.fill.HyperlinkData;
import com.bolt.report.engine.model.Expression;

import java.util.HashMap;
import java.util.Map;

public class DefaultHyperlinkHtmlBuilder implements HyperlinkHtmlBuilder {

    private static final String SINGLE_LINK = "<a href=\"{}report/view?reportId={}&{}\" target=\"{}\" >{}<a>";


    @Override
    public String build(BaseFillElement element, Object text) {
        HyperlinkData hyperlinkData = element.getHyperlinkData();
        if (!hyperlinkData.isMultiple()) {
            return buildLink(element, hyperlinkData.getSingleDefinition(), text);
        } else {
            return buildMenu(element, text);
        }
    }

    public String buildLink(BaseFillElement element, HyperlinkDefinition definition, Object text) {

        String baseUrl = getBaseUlr(element.getFillContext());

        Map<String, Object> param = buildUrlParameter(element, definition);
        String paramUrl = MapUtil.joinIgnoreNull(param, "&", "=");

        return StrUtil.format(SINGLE_LINK,
                baseUrl,
                definition.getReportId(),
                paramUrl,
                definition.getUrlTargetType(),
                text);

    }

    public String buildMenu(BaseFillElement element, Object text) {

        HyperlinkData hyperlinkData = element.getHyperlinkData();
        StringBuilder html = new StringBuilder();
        html.append("<div class=\"dropdown\">");
        html.append(" <a class=\"btn btn-default dropdown-toggle\" type=\"button\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"true\">");
        html.append(text);
        html.append("</a>");
        html.append("<ul class=\"dropdown-menu\">");
        for (HyperlinkDefinition definition : hyperlinkData.getHyperlinkDefinition()) {
            html.append("<li>");
            buildLink(element, definition, definition.getLinkName());
            html.append("</li>");
        }
        html.append("</ul>");
        return html.toString();

    }


    public String getBaseUlr(FillContext fillContext) {
        Map<String, Object> parameters = fillContext.getParameters();
        if (parameters.containsKey(ReportConstants.BASE_URL)) {
            return (String) parameters.get(ReportConstants.BASE_URL);
        } else {
            return RequestUtil.getBaseUrl(fillContext.getServletRequest());
        }
    }

    private Map<String, Object> buildUrlParameter(BaseFillElement element, HyperlinkDefinition linkDefinition) {
        FillContext fillContext = element.getFillContext();
        Expression expression = element.getExpr();
        BindData bindData = expression.getBindData();
        Map<String, String> parameter = linkDefinition.getParameter();

        Map<String, Object> urlParameter = new HashMap<>();
        parameter.forEach((k, v) -> {
            Expression exp = new Expression(v, bindData);
            Object paramValue = exp.isExecute() ? exp.execute(fillContext, null) : v;
            urlParameter.put(k, paramValue);
        });
        return urlParameter;
    }
}